package demo.terrain;

import java.util.Random;

import org.lwjgl.input.Keyboard;

import engine.core.scene.Scene;
import engine.gameObject.GameObject;
import engine.gameObject.terrain.Terrain;
import engine.gameObject.terrain.TerrainLoader;
import engine.gui.GUIStyle;
import engine.light.EnvironmentLight;
import engine.util.collada.ColladaLoader;
import engine.util.draw.Sphere;
import engine.util.gui.Profiler;
import engine.util.math.Quaternion;
import engine.util.texture.TextureLoader;

public class SimpleTerrainScene extends Scene {

	private Terrain terrain;
	private Character character;
	private Random random;
	
	public SimpleTerrainScene() {
		super("terrain");
		random = new Random(523);
	}

	@Override
	public void init() {
		setupTerrain();
		
		setupTrees();

		// a sky object
		Sphere skySphere = new Sphere(11, 10, 10);
		skySphere.setTexture(TextureLoader.loadTexture("img/demo/sky/skysphere1.png"));
		skySphere.setRotation(Quaternion.convRotAxisToQuat((float)Math.toRadians(180), 1, 0, 0));
		setSkyObject(skySphere);
		
		character = new Character();
		character.setId("player");
		character.setPosition(0, terrain.heightAt(0, 0) + 3, 0);
		addGameObject(character);
		
		setupGUI();
		
		setupCamera();

		EnvironmentLight light = new EnvironmentLight();
		light.setAmbient(0.5f, 0.5f, 0.5f);
		light.setDirection(-1, 1, -1);
		light.setDiffuse(0.5f, 0.5f, 0.5f);
		addLight(light);
	}
	
	private void setupTerrain() {
		terrain = TerrainLoader.loadRAW("img/demo/terrain/heightmap.png", 0.03f, 32, 100, new float[]{3, 11, 18});
		terrain.setTexture(new String[]{"img/demo/terrain/sand.png", "img/demo/terrain/grass.png", "img/demo/terrain/stone.png", "img/demo/terrain/snow.png"});
		terrain.setId("terrain");
		terrain.setInNearPane(false);
		addGameObject(terrain);
	}
	
	private void setupTrees() {
		//setup 20 woods with a radius of 30 over the map and add 100 trees per wood
		for(int i = 0; i < 20; i++) {
			float radius = 30;
			float area = 256 - radius;
			
			GameObject wood = new GameObject();
			
			float posX = random.nextFloat() * area - area / 2;
			float posZ = random.nextFloat() * area - area / 2;
			wood.setPosition(posX, 0, posZ);
			
			for(int j = 0; j < 100; j++) {
				float angle = random.nextFloat() * (float)Math.PI * 2;
				float r = random.nextFloat() * radius;
				
				float x = (float)Math.cos(angle) * r + posX;
				float z = (float)Math.sin(angle) * r + posZ;
				float y = terrain.heightAt(x, z);
				
				if(y < 3.5) {
					continue;
				}
				
				GameObject toAdd = null;
				double number = random.nextDouble();
				
				if(number < 0.02) {
					toAdd = ColladaLoader.importFile("model/demo/terrain/obelisk.dae", 6);
					toAdd.setColliding(true);
					toAdd.setPosition(x, y - 1, z);
				} else {
					toAdd = ColladaLoader.importFile("model/demo/terrain/mandragora.dae", 4);
					toAdd.getChildren().get(0).setColliding(true);
					toAdd.setPosition(x, y, z);
				}
				
				wood.addChild(toAdd);
			}
			
			addGameObject(wood);
		}
	}
	
	private void setupCamera() {
		setCurrentCamera(new TerrainCamera(character));
		getCurrentCamera().setNearPane(40);
		getCurrentCamera().setFarPane(200);
		getCurrentCamera().setEyeX(0);
		getCurrentCamera().setEyeZ(0);
	}
	
	private void setupGUI() {
		setGUIStyle(GUIStyle.getDefaultStyle());
		
		Profiler profiler = new Profiler(0, 0);
		profiler.setAlign(Profiler.ALIGN_LEFT);
		getWindowManager().addComponent(profiler);
	}
	
	@Override
	public void keyPressed(int key) {
		if(key == Keyboard.KEY_ESCAPE) {
			getOpenGLView().setRunning(false);
		}
	}
}
